Uma das principais e mais frequentes dúvidas em fóruns é sobre tratamento de datas. O formato brasileiro é dd/mm/yyy, porém os bancos de dados, por exemplo, trabalham com a data no formato ISO 8601, ou seja, yyyy-mm-dd.
Face a isso, muitos têm dúvidas em como converter do formato brasileiro para o ISO e vice-versa. É possível fazer isso de várias formas, mas pretendo mostrar aqui as principais delas, comparando o tempo de execução de cada uma, a fim de encontrar a mais eficiente.
Critério de Avaliação
Para a análise de desempenho, usarei a função microtime
, que retorna o timestamp atual, em microssegundos. A lógica é armazenar na variável $time
o timestamp de início da execução, para, depois, subtraí-lo do timestamp do final.
Considerarei como timestamp final o momento logo após a conversão, desconsiderando o qualquer exibição na tela. Isso porque a exibição na tela envolve acesso a periféricos (nesse caso, o dispositivo de saída, também chamado de “monitor”).
A diferença estará em microssegundos e, se for muito pequena, será mostrada em notação científica. Para forçar a exibição no formato decimal, usarei a função number_format, com precisão de 15 casas decimais.
Exemplos de Conversão de Datas
Vamos aos cinco exemplos.
O primeiro exemplo usa arrays, com as funções implode, explode, e array_reverse. É talvez o mais usado. Pelo menos é o que mais aparece por aí.
Arquivo date1.php
$time = microtime( true ); $date = '2011-01-15'; $dateBR = implode( '/', array_reverse( explode( '-', $date ) ) ); $diff = number_format( microtime( true ) - $time, 15 ); printf( "date1.php (dateBR = %s) | Tempo: %s", $dateBR, $diff ); |
O segundo exemplo usa ER’s, utilizando a função preg_replace:
Arquivo date2.php
$time = microtime( true ); $date = '2011-01-15'; $dateBR = preg_replace( '/([0-9]+)-([0-9]+)-([0-9]+)/', '$3/$2/$1', $date ); $diff = number_format( microtime( true ) - $time, 15 ); printf( "date2.php (dateBR = %s) | Tempo: %s", $dateBR, $diff ); |
O exemplo 3 usa printf e scanf (e semelhantes), sem usar variáveis auxiliares, ou seja, fazendo sscanf retornar um array, que é lido por vsprintf.
Arquivo date3.php
$time = microtime( true ); $date = '2011-01-15'; $dateBR = vsprintf( "%02d/%02d/%04d", array_reverse( sscanf( $date, "%d-%d-%d" ) ) ); $diff = number_format( microtime( true ) - $time, 15 ); printf( "date3.php (dateBR = %s) | Tempo: %s", $dateBR, $diff ); |
O exemplo 4 usa, novamente, printf e scanf (e semelhantes), mas usa variáveis auxiliares, para evitar o uso de array, da forma como é normalmente usada em linguagens como C e C++.
Arquivo date4.php
$time = microtime( true ); $date = '2011-01-15'; sscanf( $date, "%d-%d-%d", $y, $m, $d ); $dateBR = sprintf( "%02d/%02d/%04d", $d, $m, $y ); $diff = number_format( microtime( true ) - $time, 15 ); printf( "date4.php (dateBR = %s) | Tempo: %s", $dateBR, $diff ); |
Finalmente, o exemplo 5 usa a classe nativa DateTime, disponível a partir do PHP 5. Essa classe possui o método format
, que faz a conversão entre formatos.
Arquivo date5.php
$time = microtime( true ); $date = '2011-01-15'; $DateTime = new DateTime( $date ); $dateBR = $DateTime->format( 'd/m/Y' ); $diff = number_format( microtime( true ) - $time, 15 ); printf( "date5.php (dateBR = %s) | Tempo: %s", $dateBR, $diff ); |
Resultado dos Testes
Vamos executar os cinco scripts e analisar as saídas deles. Note que aparecerão a data convertida e o tempo de execução de cada um deles.
Saída:
date1.php (dateBR = 15/01/2011) | Tempo: 0.000031948089600 date2.php (dateBR = 15/01/2011) | Tempo: 0.000128984451294 date3.php (dateBR = 15/01/2011) | Tempo: 0.000048875808716 date4.php (dateBR = 15/01/2011) | Tempo: 0.000030994415283 date5.php (dateBR = 15/01/2011) | Tempo: 0.000128984451294 |
Os números podem variar conforme o computador onde os scripts são executados, além de depender da carga da CPU no momento das execuções.
Na execução acima, o mais rápido foi o date4.php. Porém o date1.php teve quase o mesmo tempo de execução. Ambos estão lado a lado, no quesito desempenho.
Ou seja, a melhor função para converter datas seria esta:
function converteData( $data ) { if ( ! strstr( $data, '/' ) ) { // $data está no formato ISO (yyyy-mm-dd) e deve ser convertida // para dd/mm/yyyy sscanf( $data, '%d-%d-%d', $y, $m, $d ); return sprintf( '%d/%d/%d', $d, $m, $y ); } else { // $data está no formato brasileiro e deve ser convertida para ISO sscanf( $data, '%d/%d/%d', $d, $m, $y ); return sprintf( '%d-%d-%d', $y, $m, $d ); } return false; } |
O tempo de execução pode variar de máquina para máquina. Testei em um Intel Core i7 de 2.6 GHz. Em alguns outros testes, date1.php ficou muito perto de date4.php, às vezes sendo até mais rápido. Porém na maioria das vezes o date4.php foi mais rápido.
Roberto Beraldo
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015